﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Diagnostics;
using ThreeByte.ActiveDeck.Config;
using System.Collections.ObjectModel;

namespace ThreeByte.ActiveDeck.Data.UserResponse
{
    [UserData(ShortTypeName="MultipleChoice")]
    public class MultipleChoiceUserData : AggregateUserData
    {

        public ObservableCollection<MultipleChoiceAnswerData> Answers { get; private set; }

        private MultipleChoiceUserData() {
            Answers = new ObservableCollection<MultipleChoiceAnswerData>();
            Answers.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Answers_CollectionChanged);
        }

        protected MultipleChoiceUserData(XElement node) : this() {
            Page = int.Parse(node.Attribute("Page").Value);

            foreach(XElement a in node.Elements(ns + "Answer")) {
                Answers.Add(MultipleChoiceAnswerData.ParseXml(a));
            } 
        }

        public MultipleChoiceUserData(int page) : this() {
            Page = page;
        }

        public override XElement ToXml() {
            XElement node = base.ToXml();
            foreach(MultipleChoiceAnswerData a in Answers) {
                node.Add(a.ToXml());
            }
            return node;
        }

        public static new MultipleChoiceUserData ParseXml(XElement node) {
            return new MultipleChoiceUserData(node);
        }


        //Update the Answer values and return true if anything changed
        public override bool UpdateUserData(AggregateUserData newUserData) {
            bool modified = false;

            List<MultipleChoiceAnswerData> unupdatedAnswers = Answers.ToList();

            if(!(newUserData is EmptyUserData)) {

                MultipleChoiceUserData newData = (MultipleChoiceUserData)newUserData;
                foreach(MultipleChoiceAnswerData a in newData.Answers) {
                    MultipleChoiceAnswerData thisAnswer = (from t in Answers
                                                           where t.Value == a.Value
                                                           select t).Single();
                    if(a.UserResponses != thisAnswer.UserResponses) {
                        modified = true;
                        thisAnswer.UserResponses = a.UserResponses;
                    }
                    unupdatedAnswers.Remove(thisAnswer);
                }
            }
            //Handle the case that newUserData does not contain a new value for a previously populated value, like when a reset happens
            foreach (MultipleChoiceAnswerData a in unupdatedAnswers) {
                if(a.UserResponses != 0) {
                    modified = true;
                }
                a.UserResponses = 0;
            }

            Refresh();
            return modified;
        }

        private Random RAND = new Random((int)DateTime.Now.Ticks);

        public void UseSampleData(bool enable) {
            //TotalResponses = 100;
            //int remaining = TotalResponses;
            if(enable) {
                foreach(MultipleChoiceAnswerData a in Answers) {
                    //a.Percent = RAND.Next(remaining);
                    a.UserResponses = RAND.Next(100);
                    //remaining -= a.UserResponses;
                }
            } else {
                foreach(MultipleChoiceAnswerData a in Answers) {
                    a.UserResponses = 0;
                }
            }


            Refresh();
        }

        void Answers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
            Refresh();
        }

        private void Refresh() {
            //Get Total Responses
            int responses = 0;
            foreach(MultipleChoiceAnswerData a in Answers) {
                responses += a.UserResponses;
            }

            TotalResponses = responses;
            //Update the percents
            if(TotalResponses > 0) {
                foreach(MultipleChoiceAnswerData a in Answers) {
                    a.Percent = (int)(a.UserResponses * 100.0 / (double)(TotalResponses));
                }
            } else {
                foreach(MultipleChoiceAnswerData a in Answers) {
                    a.Percent = 0;
                }
            }

        }

    }
}
